package com.billy.ohos.swipe.consumer;

import com.billy.ohos.swipe.*;
import com.billy.ohos.swipe.internal.SwipeHelper;

import ohos.aafwk.ability.Ability;

import ohos.agp.components.Component;

/**
 * swipe to finish Ability. make current Ability translucent to show the previous Ability
 * thanks:
 * 1. https://github.com/ikew0ng/SwipeBackLayout
 * 2. https://github.com/Simon-Leeeeeeeee/SLWidget
 *
 * @author billy.qi
 */
public class AbilitySlidingBackConsumer extends TranslucentSlidingConsumer {
    protected Ability mAbility;
    protected int initTranslation = 0;
    protected Component mPreviousAbilityContentView;
    protected boolean mHorizontalSwiping;

    public AbilitySlidingBackConsumer(Ability ability) {
        this.mAutoCloseOnWrapperDetachedFromWindow = false;
        this.mAbility = ability;
        showScrimAndShadowOutsideContentView();
        setShadowColor(0x80000000);
        setShadowSize(SmartSwipe.dp2px(10, ability));
    }

    @Override
    public boolean tryAcceptMoving(int pointerId, float downX, float downY, float dx, float dy) {
        return super.tryAcceptMoving(pointerId, downX, downY, dx, dy);
    }

    @Override
    public boolean tryAcceptSettling(int pointerId, float downX, float downY) {
        return false;
    }

    @Override
    public void onAttachToWrapper(SmartSwipeWrapper wrapper, SwipeHelper swipeHelper) {
        super.onAttachToWrapper(wrapper, swipeHelper);
    }

    @Override
    public void onDetachFromWrapper() {
        super.onDetachFromWrapper();
        resetPreviousAbilityContentView();
    }

    @Override
    protected void onOpened() {
        super.onOpened();
        if (mListeners == null || mListeners.isEmpty()) {
            if (mAbility != null) {
                mAbility.terminateAbility();
                mAbility.setTransitionAnimation(ResourceTable.Animation_anim_none, ResourceTable.Animation_anim_none);
            }
        }
        resetPreviousAbilityContentView();
    }

    @Override
    protected void onClosed() {
        super.onClosed();
        resetPreviousAbilityContentView();
    }

    private void resetPreviousAbilityContentView() {
        if (mPreviousAbilityContentView != null) {
            mPreviousAbilityContentView.setTranslationX(0);
            mPreviousAbilityContentView.setTranslationY(0);
            mPreviousAbilityContentView = null;
        }
    }

    @Override
    protected void initChildrenFormXml() {
        //do nothing
    }

    @Override
    public void onSwipeAccepted(int activePointerId, boolean settling, float initialMotionX, float initialMotionY) {
        if (mRelativeMoveFactor > 0) {
            mHorizontalSwiping = (mDirection & DIRECTION_HORIZONTAL) > 0;
            Ability previousAbility = SmartSwipeBack.findPreviousAbility(mAbility);
            if (previousAbility != null) {
                mPreviousAbilityContentView = previousAbility.findComponentById(ConstantId.ABLITY_CONTENT_ID);
                switch (mDirection) {
                    case DIRECTION_LEFT:
                        initTranslation = -(int) (mWidth * mRelativeMoveFactor);
                        break;
                    case DIRECTION_RIGHT:
                        initTranslation = (int) (mWidth * mRelativeMoveFactor);
                        break;
                    case DIRECTION_TOP:
                        initTranslation = -(int) (mHeight * mRelativeMoveFactor);
                        break;
                    case DIRECTION_BOTTOM:
                        initTranslation = (int) (mHeight * mRelativeMoveFactor);
                        break;
                    default:
                }
                movePreviousAbilityContentView(initTranslation);
            }
        }
        super.onSwipeAccepted(activePointerId, settling, initialMotionX, initialMotionY);
    }

    private void movePreviousAbilityContentView(int translation) {
        if (mPreviousAbilityContentView == null) {
            return;
        }
        if (mHorizontalSwiping) {
            mPreviousAbilityContentView.setTranslationX(translation);
        } else {
            mPreviousAbilityContentView.setTranslationY(translation);
        }
    }

    @Override
    protected void onDisplayDistanceChanged(int distanceXToDisplay, int distanceYToDisplay, int dx, int dy) {
        if (mPreviousAbilityContentView != null) {
            int translation = 0;
            switch (mDirection) {
                case DIRECTION_LEFT:
                    translation = initTranslation + (int) (mWidth * mProgress * mRelativeMoveFactor);
                    break;
                case DIRECTION_RIGHT:
                    translation = initTranslation - (int) (mWidth * mProgress * mRelativeMoveFactor);
                    break;
                case DIRECTION_TOP:
                    translation = initTranslation + (int) (mHeight * mProgress * mRelativeMoveFactor);
                    break;
                case DIRECTION_BOTTOM:
                    translation = initTranslation - (int) (mHeight * mProgress * mRelativeMoveFactor);
                    break;
                default:
            }
            movePreviousAbilityContentView(translation);
        }
        boolean horizontal = (mDirection & DIRECTION_HORIZONTAL) > 0;
        Component contentView = mWrapper.getContentView();
        if (contentView != null) {
            if (horizontal) {
                contentView.setTranslationX(distanceXToDisplay);
            } else {
                contentView.setTranslationY(distanceYToDisplay);
            }
        }
        layoutScrimView();
    }

    @Override
    protected void layoutContentView(Component contentView) {
        if (contentView != null) {
            contentView.arrange(0, 0, mWidth, mHeight);
        }
    }

    @Override
    public int clampDistanceVertical(int distanceY, int dy) {
        return super.clampDistanceVertical(distanceY, dy);
    }

    @Override
    public int clampDistanceHorizontal(int distanceX, int dx) {
        return super.clampDistanceHorizontal(distanceX, dx);
    }
}
